home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 43 / Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso / -serious- / programming / c / pmm / doku / libdoku / memlib.doc < prev    next >
Text File  |  1999-06-14  |  14KB  |  313 lines

  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
  2. * |_o_o|\\ Copyright (c) 1988-1995 Doug Walker                            *
  3. * |. o.| ||          All Rights Reserved.                                 *
  4. * | .  | ||          Written by Doug Walker                               *
  5. * | o  | ||          4701 Oak Park Road                                   *
  6. * |  . |//           Raleigh, NC 27612                                    *
  7. * ======             email: walker@unx.sas.com                            *
  8. \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  9.  
  10. This material is Copyright (c) 1988-1995 by Doug Walker.
  11. It may be distributed freely as long as the following restrictions are met:
  12.  
  13.    1.  All files present in the distribution package must be redistributed
  14.        with the package, including this documentation file.  If you 
  15.        distribute on diskette, all files must be on a single diskette.
  16.  
  17.    2.  The distributor may charge a reasonable fee to recover distribution
  18.        costs.
  19.  
  20.    3.  The distributor agrees to cease distributing the programs and data
  21.        involved if requested to do so by the author.
  22.  
  23. ------------------------------DISCLAIMER
  24.  
  25. Use this software at your own risk.  The author will not be liable for 
  26. any damage arising from the failure of this program to perform as described,
  27. or any destruction of other programs or data residing on a system 
  28. attempting to run the program.  While no damaging errors are known, the 
  29. user of this program uses it at his or her own risk.
  30.  
  31. ============================================================================
  32.  
  33. Welcome to the MemWatch Library!  The MemWatch library adds lots of memory 
  34. debugging features that you link into your program.  The library does what
  35. it can to validate your memory allocations and frees and to encourage any
  36. misuse of memory to result in a reproducable crash rather than an erratic
  37. bug.
  38.  
  39. The MemWatch library compiles under SAS/C 6.0 and above.  If the memory
  40. features are turned off, no additional code will be added to your 
  41. program.  If they are enabled, your code will call routines in the
  42. MemWatch library automatically instead of malloc, calloc, realloc, free,
  43. AllocMem, FreeMem, AllocVec, and FreeVec.  The MemWatch library also
  44. replaces the standard C library versions of getcwd(), getenv(), and
  45. strdup() since these functions call malloc().
  46.  
  47. The program-level memory debug routines are controlled by a 
  48. preprocessor symbol, MWDEBUG, and are #defined to nothing if the 
  49. symbol is not defined.  To link the program-level routines into 
  50. your code, do the following:
  51.  
  52. 1. Include the file "memwatch.h" into each file that will be
  53.    allocating or freeing memory.   (Don't include "mempriv.h" - it is
  54.    for the internal use of the memwatch.lib routines only).
  55.    If you include <stdlib.h>, make sure to include "memwatch.h"
  56.    AFTER you include <stdlib.h>.
  57.  
  58. 2. #define the symbol MWDEBUG to 1 at some point before memwatch.h 
  59.    is included.  The symbol must be defined in each compilation 
  60.    somewhere.  It could be done in an include file, in the
  61.    program file, or on the compiler command line.  If the symbol 
  62.    MWDEBUG is not defined or is defined to 0, all the  MemWatch 
  63.    routines disappear, thus adding nothing to your code size.
  64.  
  65. 3. Recompile all files in your program and link with the library
  66.    "memwatch.lib".
  67.  
  68. Unlike previous versions of MemLib, you do not need to add calls to
  69. the functions MWInit and MWTerm to make the MemWatch library work.
  70. MemWatch now takes advantage of SAS/C autoinitialization and
  71. autotermination functions to initialize and terminate the memory
  72. debugging.
  73.  
  74. The program-level MemWatch interface is described below.  Note that
  75. your code will probably not need to call any of these functions
  76. directly.
  77.  
  78. ---------------------------------------------------------------------
  79.  
  80.    void MWInit(BPTR debugfile, LONG flags, char *dbfilename);
  81.  
  82.    You are not required to call MWInit, but you may call it if
  83.    you want to change the way MemLib behaves after it has been
  84.    initialized.  If you do not call it explicitly, the autoinit
  85.    code calls it for you as described at the end of this section.
  86.  
  87.    The 'flags' parameter can be one or more of the following, ORed together 
  88.    if necessary:
  89.  
  90.    MWF_NOLOG:   If set, do not print error or warning messages.  Useful
  91.                 only if you want to turn off debugging for some reason.
  92.                 Saves some CPU time.
  93.  
  94.    MWF_CHECK:   If set, check all allocated memory each time a memory 
  95.                 routine is called.  Every AllocMem, FreeMem, malloc or 
  96.                 free call will cause all allocated memory to be examined.
  97.                 This can be extremely slow, but it's safe.
  98.  
  99.    MWF_NOFREE:  If set, do not free memory left allocated when the
  100.                 program exits.  If not set, any memory you allocated
  101.                 and did not free will be freed on your behalf.
  102.  
  103.    MWF_NOFTRASH: If set, freed memory will not be trashed.  This does
  104.                 save some time, but it is valuable to trash freed memory
  105.                 to verify you aren't still using it.
  106.  
  107.    MWF_NOFKEEP: If set, free memory immediately when FreeMem or free is
  108.                 called.  If not set, 'freed' memory will actually be kept
  109.                 on a chain and checked periodically for a change in its
  110.                 value.  If the value changes, you have written to freed
  111.                 memory.  MWF_NOFTRASH implies MWF_NOKEEP, since there is
  112.                 no point in keeping memory that you don't know the value 
  113.                 of.  If this flag is NOT set, kept memory will be freed 
  114.                 if the machine actually runs out of memory.
  115.  
  116.    MWF_NOATRASH: If set, memory will not be trashed upon allocation.  This
  117.                 also saves some time, but it is extremely valuable to trash
  118.                 allocated memory to be sure you aren't relying on side
  119.                 effects for your program to run correctly.
  120.  
  121.    MWF_SERIAL:  If you have recompiled MemWatch to use Commodore's debug.lib
  122.                 to put information to the serial port, this flag tells 
  123.                 memlib to use this feature.  If you have not recompiled
  124.                 to use debug.lib, this flag does nothing.
  125.  
  126.    If the MWF_SERIAL flag is not active, the other parameters are used to
  127.    determine where the debugging output goes as follows:
  128.  
  129.    If you specify the "debugfile" parameter, it should be the result
  130.    of a call to the AmigaDOS function Open().  The specified filehandle
  131.    will be used for all debugging messages.
  132.    
  133.    If "debugfile" is NULL but you specify a filename with the "dbfilename"
  134.    parameter, MemWatch will perform an Open() on the specified filename
  135.    WHEN AN ERROR OCCURS.  Close() will be called automatically the next
  136.    time you call MWInit() or MWTerm(), or when your program exits.
  137.  
  138.    If both "debugfile" and "dbfilename" are NULL, the AmigaDOS function
  139.    Output() is called and the result is used for the output.
  140.    
  141.    The intent is for you to provide "debugfile" if you have a convenient
  142.    place for debugging output to go already.  If you don't have a 
  143.    convenient place, you can pass the name of a console window as
  144.    "dbfilename" :
  145.  
  146.       MWInit(NULL, 0, "CON:0/0/639/199/MemLib output/AUTO/CLOSE/WAIT");
  147.  
  148.    The console window will be opened if/when something interesting 
  149.    happens, but will stay out of the way until then.  Finally, if your
  150.    program is run from the CLI or Shell, you can pass NULL for both
  151.    'debugfile' and 'dbfilename' and output will be sent to the Shell 
  152.    window.
  153.  
  154.    If you do not call MWInit() explicitly, it is called for you by the
  155.    autoinitialization routine.  The autoinitialization routine uses
  156.    the external integer variable __MWFlags as the "flags" parameter
  157.    and the external character pointer variable __MWLogName as the
  158.    "dbfilename" parameter.  You can declare these variables in your
  159.    code or allow them to be pulled in from the MemWatch library.  Their
  160.    default values as specified in the MemWatch library are:
  161.    
  162.       unsigned long __MWFlags = MWF_SERIAL;
  163.  
  164.       char *__MWLogName = "CON:0/0/639/199/MemLib/AUTO/CLOSE/WAIT";
  165.  
  166.    Note that even though the default __MWFlags value is MWF_SERIAL, the
  167.    serial port will not be used unless you edit mempriv.h to define
  168.    the symbol USEDEBUGLIB to 1 and recompile the library.  See the 
  169.    "additional features" section below for details.
  170.  
  171.    If the symbol MWDEBUG not defined to 1 or higher, MWInit() is defined
  172.    as an empty macro.
  173.  
  174. ---------------------------------------------------------------------
  175.  
  176.  
  177.    void MWTerm(void);
  178.  
  179.    You are not required to call this routine.  If you do call it, 
  180.    however, the log file is closed and all memory routines are
  181.    disabled.  Any calls to allocate memory after MWTerm() has been
  182.    called will fail!
  183.  
  184.    MWTerm() will always generate a check of all memory allocated
  185.    through the MemWatch library.
  186.  
  187.    If the symbol MWDEBUG is not defined to 1 or higher, MWTerm() is defined
  188.    as an empty macro.
  189.  
  190. ---------------------------------------------------------------------
  191.  
  192.    char *MWAllocMem(LONG size, LONG flags, char *file, int line);
  193.  
  194.    You should not call this routine directly, but your AllocMem, malloc,
  195.    realloc, and AllocVec calls will call it if the symbol MWDEBUG 
  196.    is defined to 1.
  197.  
  198. ---------------------------------------------------------------------
  199.  
  200.    void MWFreeMem(char *ptr, LONG size, char *file, int line);
  201.  
  202.    You should not call this routine directly, but your FreeMem,
  203.    FreeVec, and free calls will be defined to call it if the symbol 
  204.    MWDEBUG is defined.
  205.  
  206. ---------------------------------------------------------------------
  207.  
  208.    void MWReport(char *title, int level);
  209.  
  210.    Call this routine any time you want a report on how much memory
  211.    you are using.  The report will be sent to the debug log file.
  212.  
  213.    MWReport() always forces a MWCheck() call.
  214.  
  215.    'title' is any character string you want.  It will be used to
  216.    label the dumped output.  Use NULL for no title.
  217.  
  218.    'level' tells how much detail you want in the report.  It is one
  219.    of the following values:
  220.  
  221.    MWR_NONE - Don't print anything.
  222.    MWR_SUM  - Print current and total memory usage
  223.    MWR_FULL - Print a short description of each outstanding allocation
  224.  
  225.    If the symbol MWDEBUG is not defined to 1 or higher, MWReport() is defined
  226.    as an empty macro.
  227.  
  228. ---------------------------------------------------------------------
  229.  
  230.    void MWCheck(void);
  231.  
  232.    Call this routine when you want to verify all your allocations are
  233.    clean.  If you have set the MWF_CHECK flag, all allocations
  234.    are checked every time you do an Alloc or Free operation anyway,
  235.    but you might want to use this directly if you do not set the flag 
  236.    or if you go long periods of time without allocating memory.
  237.  
  238.    If the symbol MWDEBUG is not defined to 1 or higher, MWCheck() is 
  239.    defined as an empty macro.
  240.  
  241. ---------------------------------------------------------------------
  242.  
  243.    void MWLimit(LONG chip, LONG fast);
  244.  
  245.    Call this routine if you want to set an artificial 'cap' on the
  246.    amount of memory available.  Any allocations that ask for memory
  247.    that would push your total allocation above the specified limits
  248.    will fail, even if memory is available to fill them.  Keep in mind
  249.    that this doesn't take fragmentation into account, so it doesn't
  250.    guarantee your program will work on a smaller memory machine!
  251.    You can simulate out-of-memory conditions by calling MWLimit
  252.    with (0,0) - no allocations will ever succeed until the limit
  253.    is raised above the current usage level.
  254.  
  255.    The 'chip' parameter sets a limit on chip memory;  the 'fast'
  256.    parameter sets a limit on fast memory.  If the specified limit for
  257.    a category is -1, the limit will be set at the current usage amount.
  258.    Thus, any frees you do will improve your situation.
  259.  
  260.    If you want to remove a limit, set it to some extremely large value,
  261.    like 0x7fffffff.
  262.  
  263.    If the symbol MWDEBUG is not defined to 1 or higher, MWLimit() is 
  264.    defined as an empty macro.
  265.  
  266.  
  267. ---------------------------------------------------------------------
  268.  
  269. ADDITIONAL FEATURES
  270.  
  271. Although you can set many of memlib's options from the MWInit call,
  272. there are some that can only be set by rebuilding the library itself.
  273. You can control these features by changing some #defines in the
  274. file "mempriv.h".
  275.  
  276. The define USEDEBUGLIB controls whether MemWatch.lib will use Commodore's
  277. debug.lib to put data to the serial port instead of a file handle.  Change
  278. the definition to 1 or higher to enable this feature, then link with
  279. Commodore's debug.lib or ddebug.lib.  If USEDEBUGLIB is on, output will
  280. go to the serial port (if you link with debug.lib) or the parallel port
  281. (if you link with ddebug.lib) unless you change your preference by
  282. calling MWInit.
  283.  
  284. The define MW_HEADLEN controls how many bytes will be set aside before your
  285. allocation to act as a header.  4 is the minimum, and the default.  The
  286. header will be checked for trashing when MWCheck() is called.
  287.  
  288. The define MW_HEADSTR sets the value that header memory will be set to.  It
  289. must be a string at least MW_HEADLEN bytes long.
  290.  
  291. The define MW_TRAILLEN controls how many bytes will be set aside after your
  292. allocation to act as a trailer.  8 is the default;  any value can be chosen
  293. for a maximum, but the higher the number, the more memory is wasted each 
  294. time you allocate memory!  The trailer will be checked whenever MWCheck()
  295. is called.
  296.  
  297. The define MW_TRAILSTR sets the value that trailer memory will be set to.
  298. It must be at a string least MW_TRAILLEN bytes long.  The default is to
  299. set all trailer bytes to 0xbb.
  300.  
  301. The define MWATRASH sets the value that newly-allocated memory will be set 
  302. to.  The default is 0xaa.
  303.  
  304. The define MWFTRASH sets the value that newly-freed memory will be set to.
  305. The default is 0x55.
  306.  
  307. -----------------------------------
  308.  
  309. The enclosed program "example" shows how the MemWatch library can find
  310. problems in your code.  See the "READ.ME" file for details.
  311.  
  312.  
  313.